package ymy.common;

import ymy.GeneralConfig;
import java.util.*;

public class VirtualLink implements Comparable<VirtualLink> {
    // 中继双方车辆
    private Vehicle begv;
    private Vehicle endv;

    // 对应的通信距离
    private double transDistance;
    // 对应的选择比重
    private double selectWeight;
    // 对应的链路质量
    private double linkQuality;
    // 对应的丢包率
    private double packetLoss;
    // 对应的延迟
    private double transDelay;

    // 从停放车辆接收到的HELLO数据包个数
    private double helloPktCntPark;
    // 从移动车辆接收到的HELLO数据包个数
    private double helloPktCntMove;

    private Queue<Double> linkQualityHistory = null;

    private boolean isSheltered = false;

    private Random random = null;

    public VirtualLink() {
        this.transDistance = 0.0;
        this.selectWeight = 0.0;
        this.linkQuality = 0.0;
        this.packetLoss = 0.0;
        this.helloPktCntPark = 0.0;
        this.helloPktCntMove = 0.0;
        this.transDelay = 0.0;
        this.linkQualityHistory = new LinkedList<>();
        this.random = new Random(System.currentTimeMillis());
    }

    // 工具函数，根据预设丢包率模拟传输数据包是否丢失
    public boolean isPacketSuccess() {
        int bound = (int)(this.packetLoss * 100);
        int val = random.nextInt(100);

        if (val < bound)
            return true;
        return false;
    }

    public void incrementHelloPktCntPark() {
        this.helloPktCntPark += 1.0;
    }

    public void incrementHelloPktCntMove() {
        this.helloPktCntMove += 1.0;
    }

    public Vehicle getBegv() {
        return begv;
    }

    public void setBegv(Vehicle begv) {
        this.begv = begv;
    }

    public Vehicle getEndv() {
        return endv;
    }

    public void setEndv(Vehicle endv) {
        this.endv = endv;
    }

    public double getTransDistance() {
        return transDistance;
    }

    public void setTransDistance(double transDistance) {
        this.transDistance = transDistance;
    }

    public double getSelectWeight() {
        return selectWeight;
    }

    public void setSelectWeight(double selectWeight) {
        this.selectWeight = selectWeight;
    }

    public double getLinkQuality() {
        return linkQuality;
    }

    public void setLinkQuality(double linkQuality) {
        this.linkQuality = linkQuality;
    }

    public boolean isSheltered() {
        return isSheltered;
    }

    public void setSheltered(boolean sheltered) {
        isSheltered = sheltered;
    }

    public double getPacketLoss() {
        return packetLoss;
    }

    public void setPacketLoss(double packetLoss) {
        this.packetLoss = packetLoss;
    }

    public void setHelloPktCntPark(double helloPktCntPark) {
        this.helloPktCntPark = helloPktCntPark;
    }

    public void setHelloPktCntMove(double helloPktCntMove) {
        this.helloPktCntMove = helloPktCntMove;
    }

    public double getHelloPktCntPark() {
        return helloPktCntPark;
    }

    public double getHelloPktCntMove() {
        return helloPktCntMove;
    }

    public double getTransDelay() {
        return transDelay;
    }

    public void setTransDelay(double transDelay) {
        this.transDelay = transDelay;
    }

    public void appendLinkQualityHistory(double linkQuality) {
        if (this.linkQualityHistory.size() >= GeneralConfig.SEQUEN_LIMIT)
            this.linkQualityHistory.poll();

        this.linkQualityHistory.add(linkQuality);
    }

    public Queue<Double> getLinkQualityHistory() {
        return this.linkQualityHistory;
    }

    @Override
    public int compareTo(VirtualLink o) {
        if (this.selectWeight > o.selectWeight) {
            return -1;
        } else if (this.selectWeight < o.selectWeight) {
            return 1;
        }
        return 0;
    }

    @Override
    public String toString() {
        String str = "VIRTUAL LINK INFORMATION: {";
        str += "\n  Begin Vehicle ID = " + this.begv.getId();
        str += "\n  End Vehicle ID = " + this.endv.getId();
        str += "\n  Transport Distance = " + this.transDistance + "m";
        str += "\n  DirectedLink Quality = " + this.linkQuality;
        str += "\n  Select Weight = " + this.selectWeight;
        str += "\n  Hello Packet From Park = " + this.helloPktCntPark;
        str += "\n  Hello Packet From Move = " + this.helloPktCntMove;
        str += "\n}";
        return str;
    }
}